package fr.umlv.dnd;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;

import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.TransferHandler;

import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;

import fr.umlv.authentication.SessionHandler;
import fr.umlv.cmis.listview.CmisObjectListViewSelectionModel;
import fr.umlv.cmis.listview.ViewComponent;
import fr.umlv.model.ClientModel;

// TODO: Auto-generated Javadoc
/**
 * The Class CmisObjectTransfertHandler.
 */
public class CmisObjectTransferHandler extends TransferHandler {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;
	
	/** The bundle. */
	private final ResourceBundle bundle = ResourceBundle.getBundle("kiyut.ekspos.BrowserWindow", SessionHandler.getLocale());
	/** The bundle. */
	private final static ResourceBundle props = ResourceBundle.getBundle("kiyut.ekspos.CmisObjectTransferHandler");
	/** The max draggable file size */
	public static final int MAX_DRAGGABLE_FILESIZE = Integer.parseInt(props.getString("maxDraggableFileSize"));

	
	/** The Constant CMIS_DATA_FLAVOR. */
	public static final DataFlavor CMIS_DATA_FLAVOR = new DataFlavor(CmisObject.class, "CmisObject");
	
	/** The Constant tempDir. */
	private static final String tempDir = System.getProperty("java.io.tmpdir");
	
	/** The user advised accent. */
	boolean userAdvisedAccent = false;
	boolean userAdvised = false;
	
	/* (non-Javadoc)
	 * @see javax.swing.TransferHandler#createTransferable(javax.swing.JComponent)
	 */
	@Override
	protected Transferable createTransferable(JComponent c) {
		long totalSize = 0;
		final HashMap<CmisObject, File> fileMap = new HashMap<CmisObject, File>();

		ArrayList<File> fileList = new ArrayList<File>();
		if (c instanceof ViewComponent) {
			ViewComponent sourceComp = (ViewComponent)c;
			List<CmisObject> cmisFiles = ((CmisObjectListViewSelectionModel)sourceComp.getSelectionModel()).getSelectedFiles();
			for(CmisObject obj : cmisFiles) {
				
				File f = new File(tempDir + File.separatorChar + obj.getName());
				Document doc = null;
				if (BaseTypeId.CMIS_DOCUMENT.equals(obj.getBaseTypeId())) {
					doc = (Document) obj;
				}
				if (doc == null)
					return null;
				totalSize += doc.getContentStreamLength();
				String fileName = doc.getName();
				boolean isAccent = false;
				for (int i = 0; i < fileName.length(); i++) {
					int ch = fileName.charAt(i);
					if (ch>127)
						isAccent = true;
				}

				if (isAccent) {
					if (!userAdvisedAccent) {
						JOptionPane.showMessageDialog(c, bundle.getString("info.receive.dnd.accent.text") , bundle.getString("info.receive.dnd.accent.title"), JOptionPane.INFORMATION_MESSAGE);
						userAdvisedAccent = true;
						return null;
					}
					continue;
				}
				
				if (totalSize > MAX_DRAGGABLE_FILESIZE) {
					if (!userAdvised) {
						JOptionPane.showMessageDialog(c, bundle.getString("info.receive.dnd.largefile.text") , bundle.getString("info.receive.dnd.largefile.title"), JOptionPane.INFORMATION_MESSAGE);
						userAdvised = true;
						return null;
					}
					continue;
				}
				
				f.deleteOnExit();
				fileMap.put(obj, f);
				fileList.add(f);
			}
			if (fileMap.size()==0)
				return null;
			ClientModel.downloadCmisObjectWithProgressBar(c, fileMap);
		}

		//Collections.sort(fileList);
		Transferable transferable = new CmisObjectTransferableMarc(fileList);
		return transferable;

	}
	
    /* (non-Javadoc)
     * @see javax.swing.TransferHandler#getSourceActions(javax.swing.JComponent)
     */
    @Override
    public int getSourceActions(JComponent comp) {
        return TransferHandler.COPY_OR_MOVE;
    }
    
    /* (non-Javadoc)
     * @see javax.swing.TransferHandler#canImport(javax.swing.JComponent, java.awt.datatransfer.DataFlavor[])
     */
    @Override
    public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
        boolean b = false;
        for (int i=0; i<transferFlavors.length; i++) {
            if (transferFlavors[i].equals(DataFlavor.javaFileListFlavor)) {
                b = true;
                break;
            }
        }
        return b;
    }
	
    @Override
    protected void exportDone(JComponent source, Transferable data, int action) {
//    	System.out.println("Export done");
//    	super.exportDone(source, data, action);
//    	try {
//			ArrayList<File> fileList = (ArrayList<File>) data.getTransferData(DataFlavor.javaFileListFlavor);
//			for(File f:fileList)
//				System.out.println(f.getCanonicalPath());
//		} catch (UnsupportedFlavorException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//    	
    }
	/**
	 * The Class CmisObjectTransferableMarc.
	 */
	public class CmisObjectTransferableMarc implements Transferable {

		/** The data. */
		private List<File> data;

		/**
		 * Instantiates a new cmis object transferable marc.
		 *
		 * @param fileList the file list
		 */
		public CmisObjectTransferableMarc(List<File> fileList) {
			this.data = fileList;
		}

		  // Implementation of the Transferable interface
		  /* (non-Javadoc)
  		 * @see java.awt.datatransfer.Transferable#getTransferDataFlavors()
  		 */
  		public DataFlavor[] getTransferDataFlavors() {
		    return new DataFlavor[] { DataFlavor.javaFileListFlavor };
		  }

		  /* (non-Javadoc)
  		 * @see java.awt.datatransfer.Transferable#isDataFlavorSupported(java.awt.datatransfer.DataFlavor)
  		 */
  		public boolean isDataFlavorSupported(DataFlavor fl) {
		    return fl.equals(DataFlavor.javaFileListFlavor);
		  }

		  /* (non-Javadoc)
  		 * @see java.awt.datatransfer.Transferable#getTransferData(java.awt.datatransfer.DataFlavor)
  		 */
  		public Object getTransferData(DataFlavor fl) {
		    if (!isDataFlavorSupported(fl)) {
		      return null;
		    }

		    return data;
		  }

	}

}